//package cn.genmer.test.security.machinelearning.deeplearning4j.facialrecognition;
//
//import org.deeplearning4j.nn.api.OptimizationAlgorithm;
//import org.deeplearning4j.nn.conf.*;
//import org.deeplearning4j.nn.conf.inputs.InputType;
//import org.deeplearning4j.nn.conf.layers.ActivationLayer;
//import org.deeplearning4j.nn.conf.layers.ConvolutionLayer;
//import org.deeplearning4j.nn.conf.layers.objdetect.Yolo2OutputLayer;
//import org.deeplearning4j.nn.graph.ComputationGraph;
//import org.deeplearning4j.nn.weights.WeightInit;
//import org.deeplearning4j.optimize.listeners.ScoreIterationListener;
//import org.nd4j.evaluation.classification.Evaluation;
//import org.nd4j.linalg.activations.Activation;
//import org.nd4j.linalg.api.ndarray.INDArray;
//import org.nd4j.linalg.dataset.DataSet;
//import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
//import org.nd4j.linalg.factory.Nd4j;
//import org.nd4j.linalg.learning.config.Adam;
//
///**
// * 没跑，只是搞个例子
// */
//public class TinyYolo {
//    public static void main(String[] args) throws Exception {
//        int nBoxes = 5;
//        int numLabels = 1;
//        double lambdaNoObj = 0.5;
//        double lambdaObj = 1.0;
//        double[][] priorBoxes = {{1.08, 1.19}, {3.42, 4.41}, {6.63, 11.38}, {9.42, 5.11}, {16.62, 10.52}};
//
//        int batchSize = 64;
//        int nEpochs = 10;
//        int seed = 123;
//
//        // Load your training data and labels here
//         DataSetIterator trainData = null;
//         DataSetIterator testData = null;
//
//        ComputationGraph model = tinyYolo(nBoxes, numLabels, priorBoxes, lambdaNoObj, lambdaObj);
//        model.init();
//        model.setListeners(new ScoreIterationListener(1));
//
//        for (int i = 0; i < nEpochs; i++) {
//            while (trainData.hasNext()) {
//                DataSet ds = trainData.next();
//                model.fit(ds);
//            }
//            trainData.reset();
//        }
//
//        // Evaluate the model on test data
//        Evaluation eval = new Evaluation(numLabels);
//        while (testData.hasNext()) {
//            // 获取测试数据和标签
//            DataSet ds = testData.next();
//            INDArray[] outputs = model.output(ds.getFeatures());
//
//            // 评估模型输出
//            for (INDArray output : outputs) {
//                // 在这里进行适当的处理
//                 eval.eval(ds.getLabels(), output);
//            }
//
//            // 重置评估器
//            if (!testData.hasNext()) {
//                testData.reset();
//                eval.reset();
//            }
//        }
//
//// 打印评估结果
//        System.out.println(eval.stats());
//    }
//
//    public static ComputationGraph tinyYolo(int nBoxes, int numLabels, double[][] priorBoxCoordinates, double lambdaNoObj, double lambdaObj) {
//        NeuralNetConfiguration.Builder builder = new NeuralNetConfiguration.Builder()
//                .seed(123456L)
//                .optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
//                .gradientNormalization(GradientNormalization.RenormalizeL2PerLayer)
//                .gradientNormalizationThreshold(1.0)
//                .updater(new Adam.Builder().learningRate(1e-3).build())
//                .activation(Activation.IDENTITY)
//                .trainingWorkspaceMode(WorkspaceMode.SEPARATE)
//                .inferenceWorkspaceMode(WorkspaceMode.SEPARATE);
//
//        ComputationGraphConfiguration.GraphBuilder graphBuilder = builder.graphBuilder()
//                .addInputs("input")
//                .setInputTypes(InputType.convolutional(416, 416, 3));
//
//        addLayers(graphBuilder, 1, 3, 3, 16, 2, 2);
//        addLayers(graphBuilder, 2, 3, 16, 32, 2, 2);
//        addLayers(graphBuilder, 3, 3, 32, 64, 2, 2);
//        addLayers(graphBuilder, 4, 3, 64, 128, 2, 2);
//        addLayers(graphBuilder, 5, 3, 128, 256, 2, 2);
//        addLayers(graphBuilder, 6, 3, 256, 512, 2, 1);
//        addLayers(graphBuilder, 7, 3, 512, 1024, 0, 0);
//        addLayers(graphBuilder, 8, 3, 1024, 1024, 0, 0);
//
//        INDArray priorBoxes = Nd4j.create(priorBoxCoordinates);
//
//        graphBuilder
//                .addLayer("convolution2d_" + (9 - 1), new ConvolutionLayer.Builder(1,1)
//                        .nIn(1024)
//                        .nOut(nBoxes * (5 + numLabels))
//                        .stride(1,1)
//                        .convolutionMode(ConvolutionMode.Same)
//                        .weightInit(WeightInit.XAVIER)
//                        .activation(Activation.IDENTITY)
//                        .build(), "activation_" + (8 - 1))
//                .addLayer("outputs", new Yolo2OutputLayer.Builder()
////                        .lambdaNoObj(lambdaNoObj)
////                        .lambdaObj(lambdaObj)
//                        .boundingBoxPriors(priorBoxes)
//                        .build(), "convolution2d_" + (9 - 1))
//                .setOutputs("outputs");
//
//        ComputationGraphConfiguration conf = graphBuilder.build();
//        return new ComputationGraph(conf);
//    }
//
//    public static void addLayers(ComputationGraphConfiguration.GraphBuilder graphBuilder, int index, int n, int nIn, int nOut, int p, int s) {
//        for (int i = 0; i < n; i++) {
//            String layerName = "convolution2d_" + (index) + "_" + (i + 1);
//            graphBuilder.addLayer(layerName, new ConvolutionLayer.Builder(3,3)
//                    .nIn(nIn)
//                    .nOut(nOut)
//                    .stride(s,s)
//                    .padding(p,p)
//                    .convolutionMode(ConvolutionMode.Same)
//                    .weightInit(WeightInit.XAVIER)
//                    .activation(Activation.LEAKYRELU)
//                    .build(), "activation_" + (index - 1));
//            nIn = nOut;
//        }
//        graphBuilder.addLayer("activation_" + index, new ActivationLayer.Builder().activation(Activation.LEAKYRELU).build(), "convolution2d_" + index + "_" + n);
//    }
//}